package com.jinxin.platform.cdperprotypay.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jinxin.platform.cdperprotypay.mapper.ChargeDetailMapper;
import com.jinxin.platform.cdperprotypay.mapper.MeterDataMapper;
import com.jinxin.platform.cdperprotypay.pojo.bo.ChargeDetailBo;
import com.jinxin.platform.cdperprotypay.pojo.bo.SysHouse;
import com.jinxin.platform.cdperprotypay.pojo.bo.SysUser;
import com.jinxin.platform.cdperprotypay.pojo.domain.ChargeDetail;
import com.jinxin.platform.cdperprotypay.pojo.domain.MeterData;
import com.jinxin.platform.cdperprotypay.pojo.domain.RoomUser;
import com.jinxin.platform.cdperprotypay.pojo.form.ChargeDetailForm;
import com.jinxin.platform.cdperprotypay.pojo.form.StatisticsForm;
import com.jinxin.platform.cdperprotypay.pojo.vo.ChargeDetailVO;
import com.jinxin.platform.cdperprotypay.pojo.vo.PayNoticVO;
import com.jinxin.platform.cdperprotypay.pojo.vo.StatisticsVo;
import com.jinxin.platform.cdperprotypay.service.ChargeDetailService;
import com.jinxin.platform.cdperprotypay.support.ModularSupport;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import com.jinxin.platform.base.common.pojo.JsonResult;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 收费详情表
 * (ChargeDetail)表服务实现类
 *
 * @author zhangpeng
 * @since 2020-06-28 17:31:04
 */
@Slf4j
@Service("chargeDetailService")
public class ChargeDetailServiceImpl implements ChargeDetailService {
    @Resource
    private ChargeDetailMapper chargeDetailMapper;
    @Resource
    private ModularSupport modularSupport;
    @Resource
    private MeterDataMapper meterDataMapper;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public JsonResult queryById(String id) {
        ChargeDetail chargeDetail = this.chargeDetailMapper.queryById(id);
        return JsonResult.ok(chargeDetail);
    }

    /**
     * 通过实体作为筛选条件查询
     *
     * @param chargeDetail 实例对象
     * @return 对象列表
     */
    @Override
    public JsonResult queryAll(ChargeDetail chargeDetail) {
        List<ChargeDetail> chargeDetailList = this.chargeDetailMapper.queryAll(chargeDetail);
        return JsonResult.ok(chargeDetailList);
    }

    /**
     * 新增数据
     *
     * @param chargeDetail 实例对象
     * @return 实例对象
     */
    @Override
    public JsonResult insert(ChargeDetail chargeDetail) {
        if (chargeDetail.getRoomId() == null) {
            return JsonResult.error("房间不能为空！");
        }
        HashMap<Object, Object> map = new HashMap<>();
        map.put("roomId", chargeDetail.getRoomId());
        SysHouse sysHouse = modularSupport.getRoomById(map);
        chargeDetail.setBuildId(sysHouse.getBuildId());
        chargeDetail.setUnitId(sysHouse.getUnitId());
        chargeDetail.setVillageId(sysHouse.getVillageId());
        chargeDetail.setIsCharge("未缴费");
        int i = this.chargeDetailMapper.insert(chargeDetail);
        return i > 0 ? JsonResult.ok("新增成功", chargeDetail) : JsonResult.error("新增失败！");
    }

    /**
     * 修改数据
     *
     * @param chargeDetail 实例对象
     * @return 实例对象
     */
    @Override
    public JsonResult update(ChargeDetail chargeDetail) {
        chargeDetail.setCreater(modularSupport.getCurrentUser().getUserName());
        chargeDetail.setCreateId(modularSupport.getCurrentUser().getUserId());
        int i = this.chargeDetailMapper.update(chargeDetail);
        return i > 0 ? JsonResult.ok("修改成功！", null) : JsonResult.error("修改失败！");
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public JsonResult deleteById(String id) {
        return this.chargeDetailMapper.deleteById(id) > 0 ? JsonResult.ok("删除成功！", null) : JsonResult.error("删除失败！");
    }

    @Override
    public JsonResult findOwe(ChargeDetailForm chargeDetailForm) {
        Page<Object> page = PageHelper.startPage(chargeDetailForm.getPage(), chargeDetailForm.getLimit());
        List<ChargeDetailVO> oweLists = chargeDetailMapper.findOwe(chargeDetailForm);
        List<ChargeDetailVO> oweList = newOwe(oweLists);

        PageInfo<ChargeDetailVO> pageInfo = new PageInfo<>(oweList);
        pageInfo.setTotal(page.getTotal());
        pageInfo.setPages(page.getPages());

        return JsonResult.ok(pageInfo);
    }

    @Override
    public JsonResult findOwe2App(ChargeDetailForm chargeDetailForm) {
        List<ChargeDetailVO> oweList = chargeDetailMapper.find2App(chargeDetailForm);
        List<ChargeDetailVO> chargeDetailVOS = newOwe(oweList);
        return JsonResult.ok(chargeDetailVOS);
    }


    @Override
    public JsonResult findPaid(ChargeDetailForm chargeDetailForm) {
        Page<Object> page = PageHelper.startPage(chargeDetailForm.getPage(), chargeDetailForm.getLimit());
        List<ChargeDetailVO> paid = chargeDetailMapper.findPaid(chargeDetailForm);
        for (ChargeDetailVO c : paid) {
            HashMap<String, String> map = new HashMap<>();
            map.put("roomId", c.getRoomId());
            List<RoomUser> userByRId = modularSupport.getUserByRId(map);
            for (RoomUser r : userByRId) {
                if (!StringUtils.isEmpty(r.getUserType()) && r.getUserType().equals("11")) {
                    c.setUserName(r.getUserName());
                    c.setUserMobile(r.getUserPhone());
                    break;
                }
            }
        }
        PageInfo<ChargeDetailVO> pageInfo = new PageInfo<>(paid);
        pageInfo.setPages(page.getPages());
        pageInfo.setTotal(page.getTotal());
        return JsonResult.ok(pageInfo);
    }

    @Override
    public String resWxOrder(PayNoticVO payNoticVO) {
        try {
            SysUser currentUser = modularSupport.getCurrentUser();
            log.info("发送广播时获取当前用户：{}", currentUser);
        } catch (Exception e) {
            System.out.println(e.toString());
        }

        ChargeDetail chargeDetail = new ChargeDetail();
        chargeDetail.setSerialNum(payNoticVO.getOrderId());
        Map map = new HashMap();
        List<ChargeDetail> chargeDetails = chargeDetailMapper.queryAll(chargeDetail);
        map.put("userName", chargeDetails.get(0).getCreater());
        map.put("userId", chargeDetails.get(0).getCreateId());

        modularSupport.eventCharge(map);
        for (ChargeDetail c : chargeDetails) {
            c.setIsCharge("已缴费");
            c.setCreateTime(new Date());
            chargeDetailMapper.update(c);
        }

        return "success";
    }

    @Override
    public List<StatisticsVo> findPays2YearCycle(StatisticsForm statisticsForm) {
        return chargeDetailMapper.findPays2YearCycle(statisticsForm);
    }

    @Override
    public List<StatisticsVo> findPays2MonthCycle(StatisticsForm statisticsForm) {
        return chargeDetailMapper.findPays2MonthCycle(statisticsForm);
    }
    @Override
    public JsonResult getCharge() {
        List<ChargeDetailBo> dateList = new ArrayList<>();
        List<ChargeDetailBo> chargeAllMonth = chargeDetailMapper.getChargeAllMonth();
        for (String s : monthList()) {
            boolean flag = true;
            for (ChargeDetailBo map : chargeAllMonth) {
                if (s.equals(map.getDataTime())) {
                    dateList.add(map);
                    flag = false;
                    break;
                }
            }
            if (flag){
                ChargeDetailBo chargeDetailBo = new ChargeDetailBo();
                chargeDetailBo.setDataTime(s);
                chargeDetailBo.setSubtotal("0");
                dateList.add(chargeDetailBo);
            }
        }

        String yearCharge = chargeDetailMapper.getChargeByCycle("year");
        String monthCharge = chargeDetailMapper.getChargeByCycle("month");
        String dayCharge = chargeDetailMapper.getChargeByCycle("day");

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("year",yearCharge == null ? "0" : yearCharge);
        jsonObject.put("month",monthCharge == null ? "0" : monthCharge);
        jsonObject.put("day",dayCharge == null ? "0" : dayCharge);
        jsonObject.put("monthList",dateList);

        return JsonResult.ok(jsonObject);
    }

    public List<String> monthList(){
        SimpleDateFormat format = new SimpleDateFormat("yyyy");
        String format1 = format.format(new Date());
        List<String> monthList = new ArrayList<>();
        for (int i = 1; i < 10; i++) {
            monthList.add(format1 + "-0" + i);
        }
        monthList.add(format1 + "-10");
        monthList.add(format1 + "-11");
        monthList.add(format1 + "-12");

        return monthList;
    }

    public List<ChargeDetailVO> newOwe(List<ChargeDetailVO> oweList) {

        for (ChargeDetailVO c : oweList) {
            if (c.getPrice() == null) {
                c.setPrice("0");
            }

            String[] split1 = c.getDataTime().split("~");
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");//格式化为年月
            try {
                c.setStartTime(sdf.parse(split1[0]));
                c.setEndTime(sdf.parse(split1[1]));
            } catch (ParseException e) {
                e.printStackTrace();
            }


            HashMap<String, String> map = new HashMap<>();
            map.put("roomId", c.getRoomId());
            SysHouse room = modularSupport.getRoomById(map);
            if (room.getRoomArea() == null) {
                room.setRoomArea("0");
            }
            if (room.getPublicStall() == null) {
                room.setPublicStall("0");
            }
            if (room.getIntrathecal() == null) {
                room.setIntrathecal("0");
            }
            c.setAddress(room.getVillageName() + room.getBuildName() + "-" + room.getUnitName() + "-" + room.getRoomName());
            c.setEasyAddress(room.getBuildName() + "-" + room.getRoomName());
            List<RoomUser> userByRId = modularSupport.getUserByRId(map);
            log.info("获取的房屋人员信息：{}", JSON.toJSONString(userByRId));
            for (RoomUser r : userByRId) {
                if (!StringUtils.isEmpty(r.getUserType()) && r.getUserType().equals("11")) {
                    c.setUserName(r.getUserName());
                    c.setUserMobile(r.getUserPhone());
                    break;
                }
            }

            //通过roomId查询是否存在抄表数据
            MeterData meterData = new MeterData();
            meterData.setRoomId(c.getRoomId());
            List<MeterData> meterDataList = meterDataMapper.queryAll(meterData);
            if (meterDataList.size() > 0) {
                for (MeterData m : meterDataList) {
                    if (m.getMeterItems().equals("水费") || m.getMeterItems().equals(c.getItmesId())) {
                        if (isEffectiveDate(m.getMeterStime(), c.getStartTime(), c.getEndTime())) { // 判断是否属于同一个缴费项目,并且时间属于当期
                            c.setMeterSdata(m.getMeterSdata());
                            c.setMeterEdata(m.getMeterEdata());
//                        Double msdata = Double.parseDouble(m.getMeterSdata());
//                        Double medata = Double.parseDouble(m.getMeterEdata());
                            c.setConsumption(m.getConsumption());
                            break;
                        }
                    }
                }
            }

            if (c.getConsumption() == null) {
                c.setConsumption("0");
            }
            c.setAreaNum(room.getRoomArea());
            c.setArea(room.getRoomArea());

            //计算金额
            String lateFeeDay = c.getItemsLateFeeDay();//滞纳金从欠费的第几天开始算
            String feeProportion = c.getItemsLateFeeProportion();//滞纳金占总金额的比例
//            String countType = c.getItemsCountType();//滞纳金欠费不足月计算方式：1：月；0：实际天数
            /**
             * 计算方式：1：单价*数量；2：指定金额；3：每户单独输入；4：阶梯收费
             * 计量方式：1：建筑面积；2：用气量；3：按户收取；4：用水量；5：用电量；6：套内面积；7：公摊面积；8：楼层
             */

            if (c.getStandardCalculation().equals("1")) {
                if (c.getStandardMetering().equals("1")) {
                    c.setAreaNum(room.getRoomArea());
                    c.setMoney(totalDou(c.getPrice(), c.getAreaNum()));
                }
                if (c.getStandardMetering().equals("2") || c.getStandardMetering().equals("4") || c.getStandardMetering().equals("5")) {
                    c.setMoney(totalDou(c.getPrice(), c.getConsumption()));
                }

                if (c.getStandardMetering().equals("6")) {
                    c.setAreaNum(room.getIntrathecal());
                    c.setMoney(totalDou(c.getPrice(), c.getAreaNum()));
                }
                if (c.getStandardMetering().equals("7")) {
                    c.setAreaNum(room.getPublicStall());
                    c.setMoney(totalDou(c.getPrice(), c.getAreaNum()));
                }
            }
            if (c.getStandardCalculation().equals("2") || c.getStandardCalculation().equals("3")) {
                c.setMoney(String.format("%.2f", Double.parseDouble(c.getMoneys())));
                c.setAreaNum("");
            }
            //阶梯收费 处理
            if (c.getStandardCalculation().equals("4")) {
                //  0 - 100 : 0.5; 100 - 200 : 0.8; 200 - : 1
                String[] split = c.getPrice().split("; ");
                Double dMoney = 0.00;
                Double num = Double.parseDouble(c.getAreaNum());
                if (c.getStandardMetering().equals("2") || c.getStandardMetering().equals("4") || c.getStandardMetering().equals("5")) {
                    num = Double.parseDouble(c.getConsumption());
                    c.setAreaNum(c.getConsumption());
                    if (!c.getConsumption().equals("0")) {

                        for (int j = 0; j < split.length; j++) {
                            if (j == split.length - 1) {
                                String p = split[j].split(" - ")[0];
                                String a = split[j].split(" - ")[1].split(": ")[1];
                                int i1 = Integer.parseInt(p);
                                if (num > i1) {
                                    dMoney = Double.parseDouble(num - i1 + "") * Double.parseDouble(a) + dMoney;
                                }
                            } else {
                                String[] p = split[j].split(" - ");
                                String[] a = p[1].split(" : ");
                                int i1 = Integer.parseInt(p[0]);
                                int i2 = Integer.parseInt(a[0]);
                                if (num < i2) {
                                    dMoney = Double.parseDouble(num - i1 + "") * Double.parseDouble(a[1]) + dMoney;
                                } else {
                                    dMoney = Double.parseDouble(i2 - i1 + "") * Double.parseDouble(a[1]) + dMoney;
                                }
                            }
                        }
                    }
                } else {
                    for (int j = 0; j < split.length; j++) {
                        if (j == split.length - 1) {
                            String p = split[j].split(" - ")[0];
                            String a = split[j].split(" - ")[1].split(": ")[1];
                            int i1 = Integer.parseInt(p);
                            if (num > i1) {
                                dMoney = Double.parseDouble(num - i1 + "") * Double.parseDouble(a) + dMoney;
                            }
                        } else {
                            String[] p = split[j].split(" - ");
                            String[] a = p[1].split(" : ");
                            int i1 = Integer.parseInt(p[0]);
                            int i2 = Integer.parseInt(a[0]);
                            if (num < i2) {
                                dMoney = Double.parseDouble(num - i1 + "") * Double.parseDouble(a[1]) + dMoney;
                            } else {
                                dMoney = Double.parseDouble(i2 - i1 + "") * Double.parseDouble(a[1]) + dMoney;
                            }
                        }
                    }
                }

                c.setMoney(String.format("%.2f", dMoney));
            }
            //滞纳金处理
            if (c.getEndTime() != null && c.getIsCharge().equals("未缴费")) {
                int i = c.getEndTime().compareTo(new Date());
                if (i < 0) {  //代表已过了缴费截止时间，需要计算滞纳金等
                    int days = BetweenDays(c.getEndTime(), new Date()) - 2;  //欠费天数
                    int i1 = days - Integer.parseInt(lateFeeDay) + 1;
                    Double latFee = Double.parseDouble(c.getMoney()) * i1 * (Double.parseDouble(feeProportion) / 100);
                    ;
//                    if (i1 > 0 && countType.equals("0")){
//                        latFee = Double.parseDouble(c.getMoney()) * i1 * (Double.parseDouble(feeProportion) / 100);
//                    }
//                    if (i1 > 0 && countType.equals("1")){
//                        int ceil = i1 / 30 + 1;
//                        latFee = Double.parseDouble(c.getMoney()) * 30 * ceil * (Double.parseDouble(feeProportion) / 100);
//                    }
                    c.setLateFee(String.format("%.2f", latFee));
                }
            }
            if (c.getLateFee() == null) {
                c.setSubtotal(c.getMoney());
            } else {
                c.setSubtotal(String.format("%.2f", Double.parseDouble(c.getMoney()) + Double.parseDouble(c.getLateFee())));
            }

            if (c.getDiscount() != null) {
                String format = String.format("%.2f", Double.parseDouble(c.getSubtotal()) - Double.parseDouble(c.getDiscount()));
                c.setSubtotal(format);
                c.setDiscount(String.format("%.2f", Double.parseDouble(c.getDiscount())));
            }


            if (c.getDelLateFee() != null) {
                c.setSubtotal(String.format("%.2f", Double.parseDouble(c.getSubtotal()) - Double.parseDouble(c.getDelLateFee())));
            }

            ChargeDetail chargeDetail = new ChargeDetail();
            chargeDetail.setId(c.getId());
            chargeDetail.setLateFee(c.getLateFee());
            chargeDetail.setMoney(c.getMoney());
            chargeDetail.setSubtotal(c.getSubtotal());
            if (c.getDiscount() != null) {
                chargeDetail.setDiscount(c.getDiscount());
            }
            chargeDetailMapper.update(chargeDetail);
        }

        return oweList;
    }

    public int BetweenDays(Date startDate, Date endDate) {

        // 获取相差的天数
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        long timeInMillis1 = calendar.getTimeInMillis();
        calendar.setTime(endDate);
        long timeInMillis2 = calendar.getTimeInMillis();
        long betweenDays = (timeInMillis2 - timeInMillis1) / (1000L * 3600L * 24L);

        return (int) betweenDays;
    }

    public String totalDou(String a, String b) {
        Double fee = Double.parseDouble(a) * Double.parseDouble(b);
        return String.format("%.2f", fee);
    }

    /**
     * @param nowTime   当前时间
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return
     * @author sunran   判断当前时间在时间区间内
     */
    public static boolean isEffectiveDate(Date nowTime, Date startTime, Date endTime) {
        if (nowTime.getTime() == startTime.getTime()
                || nowTime.getTime() == endTime.getTime()) {
            return true;
        }

        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(startTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        if (date.after(begin) && date.before(end)) {
            return true;
        } else {
            return false;
        }
    }

}